package org.example.threadobjectclasscommonmethods;

import java.util.Date;
import java.util.LinkedList;

/**
 * @description: 用wait/notify来实现生产者消费者模式
 * @author: MoodAir
 * @Date: 2020/5/14 0014 22:36
 */
public class ProducerConsumerModel {

  public static void main(String[] args) {
    EventStorage eventStorage = new EventStorage();
    Producer producer = new Producer(eventStorage);
    Consumer consumer = new Consumer(eventStorage);
    new Thread(producer).start();
    new Thread(consumer).start();
  }
}

 class Producer implements Runnable {

   private final EventStorage storage;

   public Producer(
       EventStorage storage) {
     this.storage = storage;
   }

   @Override
   public void run() {
     for (int i = 0; i < 1000; i++) {
       storage.put();
     }
   }
 }

class Consumer implements Runnable {

  private final EventStorage storage;

  public Consumer(
      EventStorage storage) {
    this.storage = storage;
  }

  @Override
  public void run() {
    for (int i = 0; i < 100; i++) {
      storage.take();
    }
  }
}


class EventStorage {

  /**
   * 仓库最大数
   */
  private final Integer maxSize;


  /**
   * 仓库实体类
   */
  private final LinkedList<Date> storage;


  public EventStorage() {
    maxSize = 10;
    storage = new LinkedList<>();
  }

  /**
   * @Author: MoodAir
   * @Description: 仓库新增
   * @Date: 2020/5/16 0016 12:36
   * @param:
   * @return: void
   * @Version: 1.0
   */
  public synchronized void put() {
    //用while 判断多线程可以避免重复生产
    while (storage.size() == maxSize) {
      try {
        wait();
      } catch (InterruptedException e) {
        e.printStackTrace();
      }
    }
    storage.add(new Date());
    System.out.println("仓库里有了" + storage.size() + "个产品。");
    notify();
  }


  /**
   * @Author: MoodAir
   * @Description: 仓库消费
   * @Date: 2020/5/16 0016 12:44
   * @param:
   * @return: void
   * @Version: 1.0
   */
  public synchronized void take() {
    while (storage.size() == 0) {
      try {
        wait();
      } catch (InterruptedException e) {
        e.printStackTrace();
      }
    }
    System.out.println("拿到了" + storage.poll() + "，现在仓库还剩下" + storage.size());
    notify();
  }
}